-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ResidualVisitor to compute residuals #1388
base: main
Are you sure you want to change the base?
Conversation
…ta-only-op add count in data scan and test in catalog sql
Question: Does it make sense to expose this as the |
…-count Residual Evaluator with test
* added residual evaluator in plan files * tested counts with positional deletes * merged main
* added residual evaluator in plan files * tested counts with positional deletes * merged main * implemented batch reader in count * breaking integration test * fixed integration test * git pull main * revert * revert * revert test_partitioning_key.py * revert test_parser.py * added residual evaluator in visitor * deleted residual_evaluator.py * removed test count from test_sql.py * ignored lint type * fixed lint * working on plan_files * type ignored * make lint
Hi @Fokko @kevinjqliu @gli-chris-hao , I have implemented these suggestions with my best understanding.
It would be helpful to get fresh review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great @tusharchou Thanks for working on this. I left some comments, but this is a great start 🚀
pyiceberg/expressions/visitors.py
Outdated
val = term.eval(self.struct) | ||
if val is not None: | ||
return self.visit_true() | ||
else: | ||
return self.visit_false() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java takes a different approach and checks for NaN
:
val = term.eval(self.struct) | |
if val is not None: | |
return self.visit_true() | |
else: | |
return self.visit_false() | |
if isnan(term.eval(self.struct)): | |
return self.visit_true() | |
else: | |
return self.visit_false() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is causing a type casting problem as term.eval()
returns a L
with can be of typre str, bytes, UUID
with isnan doesn't support
pyiceberg/expressions/visitors.py:1799: error: Argument 1 to "isnan" has incompatible type "str"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
pyiceberg/expressions/visitors.py:1799: error: Argument 1 to "isnan" has incompatible type "bytes"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
pyiceberg/expressions/visitors.py:1799: error: Argument 1 to "isnan" has incompatible type "UUID"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
pyiceberg/expressions/visitors.py:1805: error: Argument 1 to "isnan" has incompatible type "str"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
pyiceberg/expressions/visitors.py:1805: error: Argument 1 to "isnan" has incompatible type "bytes"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
pyiceberg/expressions/visitors.py:1805: error: Argument 1 to "isnan" has incompatible type "UUID"; expected "Union[SupportsFloat, SupportsIndex]" [arg-type]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi@Fokko, I would require some help here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to help mypy
here a bit:
val = term.eval(self.struct) | |
if val is not None: | |
return self.visit_true() | |
else: | |
return self.visit_false() | |
val = term.eval(self.struct) | |
if isinstance(val, SupportsFloat) and isnan(val): | |
return self.visit_true() | |
else: | |
return self.visit_false() |
The nan
check will only be done on float
and double
columns, but mypy doesn't know that, so we have to help it a bit :)
* added residual evaluator in plan files * tested counts with positional deletes * merged main * implemented batch reader in count * breaking integration test * fixed integration test * git pull main * revert * revert * revert test_partitioning_key.py * revert test_parser.py * added residual evaluator in visitor * deleted residual_evaluator.py * removed test count from test_sql.py * ignored lint type * fixed lint * working on plan_files * type ignored * make lint * explicit delete files len is zero * residual eval only if manifest is true * default residual is always true * used projection schema * refactored residual in plan files
closes issue: Count rows as a metadata-only operation #1223